home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / tutorials / geometer / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  29.4 KB  |  1,106 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <strings.h>
  20. #include "parse.h"
  21.  
  22. long    restable, idtable;
  23.  
  24. void inittables()
  25. {
  26.     restable = newtable(1000);
  27.     idtable = newtable(2000);
  28.     
  29.     addentry(restable, ".geometry", _geometry);
  30.     addentry(restable, ".vertex", _vertex);
  31.     addentry(restable, ".line", _line);
  32.     addentry(restable, ".circle", _circle);
  33.     addentry(restable, ".conic", _conic);
  34.     addentry(restable, ".bezier", _bezier);
  35.     addentry(restable, ".ratio", _ratio);
  36.     addentry(restable, ".length", _length);
  37.     addentry(restable, ".angle", _angle);
  38.     addentry(restable, ".vertpath", _vertpath);
  39.     addentry(restable, ".animation", _animation);
  40.     addentry(restable, ".ray12", _ray12);
  41.     addentry(restable, ".longline", _longline);
  42.     addentry(restable, ".segment", _segment);
  43.     addentry(restable, ".diamond", _diamond);
  44.     addentry(restable, ".plus", _plus);
  45.     addentry(restable, ".cross", _cross);
  46.     addentry(restable, ".nomark", _nomark);
  47.     addentry(restable, ".soliddiamond", _soliddiamond);
  48.     addentry(restable, ".black", _black);
  49.     addentry(restable, ".red", _red);
  50.     addentry(restable, ".green", _green);
  51.     addentry(restable, ".blue", _blue);
  52.     addentry(restable, ".yellow", _yellow);
  53.     addentry(restable, ".cyan", _cyan);
  54.     addentry(restable, ".magenta", _magenta);
  55.     addentry(restable, ".white", _white);
  56.     addentry(restable, ".invisible", _invisible);
  57.     addentry(restable, ".smear", _smear);
  58.     addentry(restable, ".blink", _blink);
  59.     addentry(restable, ".c0", _c0);
  60.     addentry(restable, ".c1", _c1);
  61.     addentry(restable, ".c2", _c2);
  62.     addentry(restable, ".c3", _c3);
  63.     addentry(restable, ".c4", _c4);
  64.     addentry(restable, ".c5", _c5);
  65.     addentry(restable, ".c6", _c6);
  66.     addentry(restable, ".c7", _c7);
  67.     addentry(restable, ".c8", _c8);
  68.     addentry(restable, ".c9", _c9);
  69.     addentry(restable, ".c10", _c10);
  70.     addentry(restable, ".c11", _c11);
  71.     addentry(restable, ".c12", _c12);
  72.     addentry(restable, ".c13", _c13);
  73.     addentry(restable, ".c14", _c14);
  74.     addentry(restable, ".c15", _c15);
  75.     addentry(restable, ".c16", _c16);
  76.     addentry(restable, ".c17", _c17);
  77.     addentry(restable, ".c18", _c18);
  78.     addentry(restable, ".c19", _c19);
  79.     addentry(restable, ".c20", _c20);
  80.     addentry(restable, ".c21", _c21);
  81.     addentry(restable, ".c22", _c22);
  82.     addentry(restable, ".c23", _c23);
  83.     addentry(restable, ".c24", _c24);
  84.     addentry(restable, ".c25", _c25);
  85.     addentry(restable, ".c26", _c26);
  86.     addentry(restable, ".c27", _c27);
  87.     addentry(restable, ".c28", _c28);
  88.     addentry(restable, ".c29", _c29);
  89.     addentry(restable, ".c30", _c30);
  90.     addentry(restable, ".c31", _c31);
  91.     addentry(restable, ".L0", _l0);
  92.     addentry(restable, ".L1", _l1);
  93.     addentry(restable, ".L2", _l2);
  94.     addentry(restable, ".L3", _l3);
  95.     addentry(restable, ".L4", _l4);
  96.     addentry(restable, ".L5", _l5);
  97.     addentry(restable, ".L6", _l6);
  98.     addentry(restable, ".L7", _l7);
  99.     addentry(restable, ".L8", _l8);
  100.     addentry(restable, ".L9", _l9);
  101.     addentry(restable, ".L10", _l10);
  102.     addentry(restable, ".L11", _l11);
  103.     addentry(restable, ".L12", _l12);
  104.     addentry(restable, ".L13", _l13);
  105.     addentry(restable, ".L14", _l14);
  106.     addentry(restable, ".L15", _l15);
  107.     addentry(restable, ".L16", _l16);
  108.     addentry(restable, ".L17", _l17);
  109.     addentry(restable, ".L18", _l18);
  110.     addentry(restable, ".L19", _l19);
  111.     addentry(restable, ".L20", _l20);
  112.     addentry(restable, ".L21", _l21);
  113.     addentry(restable, ".L22", _l22);
  114.     addentry(restable, ".L23", _l23);
  115.     addentry(restable, ".L24", _l24);
  116.     addentry(restable, ".L25", _l25);
  117.     addentry(restable, ".L26", _l26);
  118.     addentry(restable, ".L27", _l27);
  119.     addentry(restable, ".L28", _l28);
  120.     addentry(restable, ".L29", _l29);
  121.     addentry(restable, ".L30", _l30);
  122.     addentry(restable, ".L31", _l31);
  123.     addentry(restable, ".free", _free);
  124.     addentry(restable, ".vonl", _vonl);
  125.     addentry(restable, ".vonc", _vonc);
  126.     addentry(restable, ".v.ll", _v_ll);
  127.     addentry(restable, ".v.vvmid", _v_vvmid);
  128.     addentry(restable, ".v.lc", _v_lc);
  129.     addentry(restable, ".v.cc", _v_cc);
  130.     addentry(restable, ".v.vvratio", _v_vvratio);
  131.     addentry(restable, ".v.avv", _v_avv);
  132.     addentry(restable, ".v.ccenter", _v_ccenter);
  133.     addentry(restable, ".v.lvmirror", _v_lvmirror);
  134.     addentry(restable, ".l.vv", _l_vv);
  135.     addentry(restable, ".l.vlperp", _l_vlperp);
  136.     addentry(restable, ".l.vlpar", _l_vlpar);
  137.     addentry(restable, ".l.vc", _l_vc);
  138.     addentry(restable, ".l.ccext", _l_ccext);
  139.     addentry(restable, ".l.ccint", _l_ccint);
  140.     addentry(restable, ".c.vv", _c_vv);
  141.     addentry(restable, ".c.vvv", _c_vvv);
  142.     addentry(restable, ".c.lll", _c_lll);
  143.     addentry(restable, ".c.vlen", _c_vlen);
  144.     addentry(restable, ".c.ccinv", _c_ccinv);
  145.     addentry(restable, ".c.lcinv", _c_lcinv);
  146.     addentry(restable, ".bez.vvvv", _bez_vvvv);
  147.     addentry(restable, ".ratio.vvv", _ratio_vvv);
  148.     addentry(restable, ".len.vv", _len_vv);
  149.     addentry(restable, ".len.plus", _len_plus);
  150.     addentry(restable, ".len.minus", _len_minus);
  151.     addentry(restable, ".len.f", _len_f);
  152.     addentry(restable, ".len.times", _len_times);
  153.     addentry(restable, ".len.divide", _len_divide);
  154.     addentry(restable, ".a.vvv", _a_vvv);
  155.     addentry(restable, ".vpath", _vpath);
  156.     addentry(restable, ".animate", _animate);
  157.     addentry(restable, ".conic.vvvvv", _conic_vvvvv);
  158.     addentry(restable, ".text", _text);
  159.     addentry(restable, ".vonconic", _vonconic);
  160.     addentry(restable, ".l.conicv", _l_conicv);
  161.     addentry(restable, ".v.vcinv", _v_vcinv);
  162.     addentry(restable, ".conic.lllll", _conic_lllll);
  163.     addentry(restable, ".v.lconic", _v_lconic);
  164.     addentry(restable, ".macro", _macro);
  165. }
  166.  
  167. enum resclass {
  168.     GEOMETRY, PRIMITIVE, LINETYPE, VERTEXTYPE, COLOR, LAYER,
  169.     MAKEVERTEX, MAKELINE, MAKECIRCLE, MAKEBEZIER, MAKELENGTH, 
  170.     MAKEANGLE, MAKETEXT, MAKEVPATH, MAKEANIMATE, MAKERATIO, 
  171.     MAKECOMMENT, MAKECONIC, MACRO, 
  172. };
  173.  
  174. static long minortype;
  175.  
  176. long reswordtype(reservedword rw)
  177. {
  178.     switch (rw) {
  179.         case _float: case _int2: case _int4: case _none:
  180.         parseerror("Bad reserved word\n");
  181.         return GEOMETRY;
  182.         case _geometry:
  183.         minortype = 0; return GEOMETRY;
  184.         case _vertex:
  185.         minortype = 1; return PRIMITIVE;
  186.         case _line:
  187.         minortype = 2; return PRIMITIVE;
  188.         case _circle:
  189.         minortype = 3; return PRIMITIVE;
  190.         case _bezier:
  191.         minortype = 5; return PRIMITIVE;
  192.         case _angle:
  193.         minortype = 6; return PRIMITIVE;
  194.         case _ratio:
  195.         minortype = 7; return PRIMITIVE;
  196.         case _length:
  197.         minortype = 8; return PRIMITIVE;
  198.         case _vertpath:
  199.         minortype = 9; return PRIMITIVE;
  200.         case _animation:
  201.         minortype = 10; return PRIMITIVE;
  202.     case _conic:
  203.         minortype = 11; return PRIMITIVE;
  204.         case _ray12:
  205.         minortype = 1; return LINETYPE;
  206.         case _longline:
  207.         minortype = 2; return LINETYPE;
  208.         case _segment:
  209.         minortype = 3; return LINETYPE;
  210.         case _diamond:
  211.         minortype = 1; return VERTEXTYPE;
  212.         case _plus:
  213.         minortype = 2; return VERTEXTYPE;
  214.         case _cross:
  215.         minortype = 3; return VERTEXTYPE;
  216.         case _nomark:
  217.         minortype = 4; return VERTEXTYPE;
  218.         case _soliddiamond:
  219.         minortype = 5; return VERTEXTYPE;
  220.         case _black:
  221.         minortype = 0; return COLOR;
  222.         case _red:
  223.         minortype = 1; return COLOR;
  224.         case _green:
  225.         minortype = 2; return COLOR;
  226.         case _blue:
  227.         minortype = 4; return COLOR;
  228.         case _yellow:
  229.         minortype = 3; return COLOR;
  230.         case _cyan:
  231.         minortype = 6; return COLOR;
  232.         case _magenta:
  233.         minortype = 5; return COLOR;
  234.         case _white:
  235.         minortype = 7; return COLOR;
  236.         case _invisible:
  237.         minortype = -1; return COLOR;
  238.         case _smear:
  239.         minortype = -2; return COLOR;
  240.     case _blink:
  241.         minortype = -3; return COLOR;
  242.         case _c0: case _c1: case _c2: case _c3: case _c4:
  243.         case _c5: case _c6: case _c7: case _c8: case _c9:
  244.         case _c10: case _c11: case _c12: case _c13: case _c14:
  245.         case _c15: case _c16: case _c17: case _c18: case _c19: 
  246.     case _c20: case _c21: case _c22: case _c23: case _c24:
  247.     case _c25: case _c26: case _c27: case _c28: case _c29:
  248.     case _c30: case _c31:
  249.         minortype = (long)rw - (long)_c0;
  250.         return COLOR;
  251.         case _l0: case _l1: case _l2: case _l3: case _l4: case _l5:
  252.         case _l6: case _l7: case _l8: case _l9: case _l10: case _l11:
  253.         case _l12: case _l13: case _l14: case _l15: case _l16: case _l17:
  254.         case _l18: case _l19: case _l20: case _l21: case _l22: case _l23:
  255.         case _l24: case _l25: case _l26: case _l27: case _l28: case _l29:
  256.         case _l30: case _l31:
  257.         minortype = (long)rw - (long)_l0;
  258.         return LAYER;
  259.         case _free:
  260.         minortype = 1; return MAKEVERTEX;
  261.         case _vonl:
  262.         minortype = 2; return MAKEVERTEX;
  263.         case _vonc:
  264.         minortype = 3; return MAKEVERTEX;
  265.         case _v_ll:
  266.         minortype = 4; return MAKEVERTEX;
  267.         case _v_vvmid:
  268.         minortype = 5; return MAKEVERTEX;
  269.         case _v_lc:
  270.         minortype = 6; return MAKEVERTEX;
  271.         case _v_cc:
  272.         minortype = 7; return MAKEVERTEX;
  273.         case _v_vvratio:
  274.         minortype = 8; return MAKEVERTEX;
  275.         case _v_avv:
  276.         minortype = 9; return MAKEVERTEX;
  277.     case _v_ccenter:
  278.         minortype = 10; return MAKEVERTEX;
  279.     case _v_lvmirror:
  280.         minortype = 11; return MAKEVERTEX;
  281.     case _vonconic:
  282.         minortype = 12; return MAKEVERTEX;
  283.     case _v_vcinv:
  284.         minortype = 13; return MAKEVERTEX;
  285.     case _v_lconic:
  286.         minortype = 14; return MAKEVERTEX;
  287.         case _l_vv:
  288.         minortype = 1; return MAKELINE;
  289.         case _l_vlperp:
  290.         minortype = 2; return MAKELINE;
  291.         case _l_vlpar:
  292.         minortype = 3; return MAKELINE;
  293.         case _l_vc:
  294.         minortype = 4; return MAKELINE;
  295.         case _l_ccext:
  296.         minortype = 5; return MAKELINE;
  297.         case _l_ccint:
  298.         minortype = 6; return MAKELINE;
  299.     case _l_conicv:
  300.         minortype = 7; return MAKELINE;
  301.         case _c_vv:
  302.         minortype = 1; return MAKECIRCLE;
  303.         case _c_vvv:
  304.         minortype = 2; return MAKECIRCLE;
  305.         case _c_vlen:
  306.         minortype = 3; return MAKECIRCLE;
  307.         case _c_lll:
  308.         minortype = 4; return MAKECIRCLE;
  309.     case _c_ccinv:
  310.         minortype = 5; return MAKECIRCLE;
  311.     case _c_lcinv:
  312.         minortype = 6; return MAKECIRCLE;
  313.         case _bez_vvvv:
  314.         minortype = 1; return MAKEBEZIER;
  315.         case _ratio_vvv:
  316.         minortype = 1; return MAKERATIO;
  317.         case _len_vv:
  318.         minortype = 1; return MAKELENGTH;
  319.         case _len_plus:
  320.         minortype = 2; return MAKELENGTH;
  321.         case _len_minus:
  322.         minortype = 3; return MAKELENGTH;
  323.         case _len_f:
  324.         minortype = 4; return MAKELENGTH;
  325.         case _len_times:
  326.         minortype = 5; return MAKELENGTH;
  327.         case _len_divide:
  328.         minortype = 6; return MAKELENGTH;
  329.         case _a_vvv:
  330.         minortype = 1; return MAKEANGLE;
  331.         case _vpath:
  332.         minortype = 0; return MAKEVPATH;
  333.         case _animate:
  334.         minortype = 0; return MAKEANIMATE;
  335.         case _text:
  336.         minortype = 0; return MAKETEXT;
  337.     case _comment:
  338.         minortype = 0; return MAKECOMMENT;
  339.     case _conic_vvvvv:
  340.         minortype = 1; return MAKECONIC;
  341.     case _conic_lllll:
  342.         minortype = 2; return MAKECONIC;
  343.     case _macro:
  344.         minortype = 0; return MACRO;
  345.     }
  346. }
  347.  
  348. FILE *globalfp;
  349.  
  350. long readstring()
  351. {
  352.     if (gettoken(globalfp) == Str) return 1;
  353.     parseerror("Expected string");
  354.     return 0;
  355. }
  356.  
  357. long readfloat()
  358. {
  359.     tokentype t;
  360.  
  361.     if ((t = gettoken(globalfp)) == Float) return 1;
  362.     if (t == Integer) {
  363.     floattoken = longtoken;
  364.     return 1;
  365.     }
  366.     parseerror("Expected float");
  367.     return 0;
  368. }
  369.  
  370. long readinteger()
  371. {
  372.     if (gettoken(globalfp) == Integer) return 1;
  373.     parseerror("Expected integer");
  374.     return 0;
  375. }
  376.  
  377. long readsemicolon()
  378. {
  379.     if (gettoken(globalfp) == Semicolon) return 1;
  380.     parseerror("Expected ';'");
  381.     return 0;
  382. }
  383.  
  384. long readopen()
  385. {
  386.     if (gettoken(globalfp) == Open) return 1;
  387.     parseerror("Expected '('");
  388.     return 0;
  389. }
  390.  
  391. long readclose()
  392. {
  393.     if (gettoken(globalfp) == Close) return 1;
  394.     parseerror("Expected ')'");
  395.     return 0;
  396. }
  397.  
  398. long readopencurly()
  399. {
  400.     if (gettoken(globalfp) == OpenCurly) return 1;
  401.     parseerror("Expected '{'");
  402.     return 0;
  403. }
  404.  
  405. long readclosecurly()
  406. {
  407.     if (gettoken(globalfp) == CloseCurly) return 1;
  408.     parseerror("Expected '}'");
  409.     return 0;
  410. }
  411.  
  412. long readequal()
  413. {
  414.     if (gettoken(globalfp) == Equal) return 1;
  415.     parseerror("Expected '='");
  416.     return 0;
  417. }
  418.  
  419. long readcomma()
  420. {
  421.     if (gettoken(globalfp) == Comma) return 1;
  422.     parseerror("Expected ','");
  423.     return 0;
  424. }
  425.  
  426. long readreserved()
  427. {
  428.     if (gettoken(globalfp) != Reserved) {
  429.         parseerror("Expected reserved word");
  430.     return 0;
  431.     }
  432.     if (lookup(restable, texttoken) == 0) {
  433.         char str[200];
  434.     sprintf(str, "unrecognized reserved word: %s", texttoken);
  435.     parseerror(str);
  436.     return 0;
  437.     }
  438.     return 1;
  439. }
  440.  
  441. long readidentifier()
  442. {
  443.     if (gettoken(globalfp) == Identifier) return 1;
  444.     parseerror("Expected identifier");
  445.     return 0;
  446. }
  447.  
  448. // default property values:
  449.  
  450. long defcolor, deflayers;
  451. reservedword deflinetype, defverttype;
  452. char defname[100];
  453.  
  454. void setdefaultproperties()
  455. {
  456.     defcolor = 7;           // white
  457.     deflayers = 0xffffffff; // all layers
  458.     deflinetype = _segment;
  459.     defverttype = _diamond;
  460.     defname[0] = (char)0;   // no name
  461. }
  462.  
  463. long parseproperties()
  464. {
  465.     symtableentry *s;
  466.  
  467.     while (1) switch (gettoken(globalfp)) {
  468.     case Comma:
  469.         switch (gettoken(globalfp)) {
  470.         case Reserved:
  471.             s = lookup(restable, texttoken);
  472.             if (s == 0) {
  473.             parseerror("unrecognized reserved word");
  474.             return 0;
  475.             }
  476.             switch(reswordtype(s->value)) {
  477.             case COLOR:
  478.                 defcolor = minortype;
  479.                 break;
  480.             case LINETYPE:
  481.                 switch(minortype) {
  482.                 case 1:
  483.                     deflinetype = _ray12;
  484.                     break;
  485.                 case 2:
  486.                     deflinetype = _longline;
  487.                     break;
  488.                 case 3:
  489.                     deflinetype = _segment;
  490.                     break;
  491.                 }
  492.                 break;
  493.             case VERTEXTYPE:
  494.                 switch(minortype) {
  495.                 case 1:
  496.                     defverttype = _diamond;
  497.                     break;
  498.                 case 2:
  499.                     defverttype = _plus;
  500.                     break;
  501.                 case 3:
  502.                     defverttype = _cross;
  503.                     break;
  504.                 case 4:
  505.                     defverttype = _nomark;
  506.                     break;
  507.                 case 5:
  508.                     defverttype = _soliddiamond;
  509.                     break;
  510.                 }
  511.                 break;
  512.             case LAYER:
  513.                 if (deflayers == 0xffffffff) deflayers = 0;
  514.                 deflayers |= (1 << minortype);
  515.                 break;
  516.             default:
  517.                 parseerror("bad properties");
  518.                 return 0;
  519.             }
  520.             break;
  521.         case Str:
  522.             strcpy(defname, texttoken);
  523.             break;
  524.         default:
  525.             parseerror("bad properties");
  526.             return 0;
  527.         }
  528.         break;
  529.     case Close:
  530.         if (readsemicolon() == 0) return 0;
  531.         return 1;
  532.     default:
  533.         parseerror("bad properties");
  534.         return 0;
  535.     }
  536. }
  537.  
  538. symtableentry *readvertex()
  539. {
  540.     symtableentry *s;
  541.  
  542.     if (readidentifier() == 0 || (s = lookup(idtable, texttoken)) == 0) {
  543.     parseerror("expected vertex");
  544.     return (symtableentry *)0;
  545.     }
  546.     if (s->value != _vertex) {
  547.     parseerror("expected vertex");
  548.     return (symtableentry *)0;
  549.     }
  550.     return s;
  551. }
  552.  
  553. symtableentry *readline()
  554. {
  555.     symtableentry *s;
  556.  
  557.     if (readidentifier() == 0 || (s = lookup(idtable, texttoken)) == 0) {
  558.     parseerror("expected line");
  559.     return (symtableentry *)0;
  560.     }
  561.     if (s->value != _line) {
  562.     parseerror("expected line");
  563.     return (symtableentry *)0;
  564.     }
  565.     return s;
  566. }
  567.  
  568. symtableentry *readcircle()
  569. {
  570.     symtableentry *s;
  571.  
  572.     if (readidentifier() == 0 || (s = lookup(idtable, texttoken)) == 0) {
  573.     parseerror("expected circle");
  574.     return (symtableentry *)0;
  575.     }
  576.     if (s->value != _circle) {
  577.     parseerror("expected circle");
  578.     return (symtableentry *)0;
  579.     }
  580.     return s;
  581. }
  582.  
  583. symtableentry *readconic()
  584. {
  585.     symtableentry *s;
  586.  
  587.     if (readidentifier() == 0 || (s = lookup(idtable, texttoken)) == 0) {
  588.     parseerror("expected conic");
  589.     return (symtableentry *)0;
  590.     }
  591.     if (s->value != _conic) {
  592.     parseerror("expected conic");
  593.     return (symtableentry *)0;
  594.     }
  595.     return s;
  596. }
  597.  
  598. symtableentry *readlength()
  599. {
  600.     symtableentry *s;
  601.  
  602.     if (readidentifier() == 0 || (s = lookup(idtable, texttoken)) == 0) {
  603.     parseerror("expected length");
  604.     return (symtableentry *)0;
  605.     }
  606.     if (s->value != _length) {
  607.     parseerror("expected length");
  608.     return (symtableentry *)0;
  609.     }
  610.     return s;
  611. }
  612.  
  613. primitive *addprim(reservedword type, primitive *c1, primitive *c2, 
  614.                 primitive *c3, primitive *c4, primitive *c5,
  615.         constrainttype c, symtableentry *s)
  616. {
  617.     primitive *p;
  618.  
  619.     switch (type) {
  620.     case _vertex:
  621.         p = new vertex;
  622.         ((vertex *)p)->type = defverttype;
  623.         break;
  624.     case _line:
  625.         p = new line;
  626.         ((line *)p)->type = deflinetype;
  627.         break;
  628.     case _circle:
  629.         p = new circle;
  630.         break;
  631.     case _length:
  632.         p = new length;
  633.         break;
  634.     case _bezier:
  635.         p = new bezier;
  636.         break;
  637.     case _comment:
  638.         p = new comment;
  639.         break;
  640.     case _text:
  641.         p = new text;
  642.         break;
  643.     case _conic:
  644.         p = new conic;
  645.         break;
  646.     default:
  647.         fprintf(stderr, "bad primitive type\n");
  648.         return 0;
  649.     }
  650.     strcpy(p->name, defname);
  651.     p->Color = defcolor;
  652.     p->layers = deflayers;
  653.     p->c.p1 = c1;
  654.     p->c.p2 = c2;
  655.     p->c.p3 = c3;
  656.     p->c.p4 = c4;
  657.     p->c.p5 = c5;
  658.     p->c.type = c;
  659.     s->p = p;
  660.     p->st = s;
  661.     addprimitive(p);
  662.     return p;
  663. }
  664.  
  665. struct parseinfo {
  666.     reservedword rw[6];
  667.     reservedword type;
  668.     constrainttype ctype;
  669. } prselist[] = {
  670.     {_float,_float,_none,_none,_none,_none,_vertex,VERTFREE},            // 0
  671.     {_vertex,_vertex,_none,_none,_none,_none,_vertex,VERTVERTVERTMID},
  672.     {_line,_line,_none,_none,_none,_none,_vertex,VERTLINELINE},
  673.     {_vertex,_circle,_none,_none,_none,_none,_vertex,VERTCIRCVERTINV},
  674.     {_line,_circle,_int2,_none,_none,_none,_vertex,VERTLINECIRC1},
  675.     {_circle,_circle,_int2,_none,_none,_none,_vertex,VERTCIRCCIRC1},    // 5
  676.     {_line,_vertex,_none,_none,_none,_none,_vertex,VERTLINEVERTMIRROR},
  677.     {_vertex,_vertex,_length,_none,_none,_none,_vertex,VERTVERTVERTRATIO},
  678.     {_length,_vertex,_vertex,_none,_none,_none,_vertex,VERTANGLEVERTVERT},
  679.     {_circle,_none,_none,_none,_none,_none,_vertex,VERTCIRCCENTER},
  680.     {_line,_float,_float,_none,_none,_none,_vertex,VERTONLINE},            // 10
  681.     {_circle,_float,_float,_none,_none,_none,_vertex,VERTONCIRCLE},
  682.     {_conic,_float,_float,_none,_none,_none,_vertex,VERTONCONIC},
  683.     {_vertex,_vertex,_none,_none,_none,_none,_line,LINEVERTVERT},
  684.     {_vertex,_line,_none,_none,_none,_none,_line,LINEVERTLINEPERP},
  685.     {_vertex,_line,_none,_none,_none,_none,_line,LINEVERTLINEPAR},      // 15
  686.     {_vertex,_circle,_int2,_none,_none,_none,_line,LINEVERTCIRC1},
  687.     {_circle,_circle,_int2,_none,_none,_none,_line,LINECIRCCIRCEXT1},
  688.     {_circle,_circle,_int2,_none,_none,_none,_line,LINECIRCCIRCINT1},
  689.     {_conic,_vertex,_int2,_none,_none,_none,_line,LINETANGENTCONIC1},
  690.     {_vertex,_vertex,_none,_none,_none,_none,_circle,CIRCVERTVERT},     // 20
  691.     {_circle,_circle,_none,_none,_none,_none,_circle,CIRCCIRCCIRCINV},
  692.     {_line,_circle,_none,_none,_none,_none,_circle,CIRCLINECIRCINV},
  693.     {_vertex,_length,_none,_none,_none,_none,_circle,CIRCVERTLEN},
  694.     {_vertex,_vertex,_vertex,_none,_none,_none,_circle,CIRCVERTVERTVERT},
  695.     {_line,_line,_line,_int4,_none,_none,_circle,CIRCLINELINELINE1},    // 25
  696.     {_vertex,_vertex,_vertex,_vertex,_none,_none,_bezier,BEZVERTVERTVERTVERT},
  697.     {_vertex,_vertex,_vertex,_vertex,_vertex,_none,_conic,CONICFIVEVERT},
  698.     {_vertex,_vertex,_vertex,_none,_none,_none,_length,RATIOVERTVERTVERT},
  699.     {_vertex,_vertex,_none,_none,_none,_none,_length,LENVERTVERT},
  700.     {_float,_none,_none,_none,_none,_none,_length,LENFLOAT},            // 30
  701.     {_length,_length,_none,_none,_none,_none,_length,LENPLUSLENLEN},
  702.     {_length,_length,_none,_none,_none,_none,_length,LENMINUSLENLEN},
  703.     {_length,_length,_none,_none,_none,_none,_length,LENTIMESLENLEN},
  704.     {_length,_length,_none,_none,_none,_none,_length,LENDIVLENLEN},
  705.     {_float,_none,_none,_none,_none,_none,_length,ANGLEFLOAT},            // 35
  706.     {_vertex,_vertex,_vertex,_none,_none,_none,_length,ANGLEVERTVERTVERT},
  707.     {_length,_length,_none,_none,_none,_none,_length,ANGLEANGLELEN},
  708.     {_length,_none,_none,_none,_none,_none,_length,ANGLEANGLETRISECT},
  709.     {_line,_line,_line,_line,_line,_none,_conic,CONICFIVELINE},
  710.     {_line,_conic,_int2,_none,_none,_none,_vertex,VERTLINECONIC1},      // 40
  711. };
  712.  
  713. long parsealine(long n, char *name)
  714. {
  715.     float f1 = 1.0e30, f2 = 1.0e30;
  716.     symtableentry *s, *sl[5];
  717.     long slistptr = 0;
  718.     primitive *p;
  719.     parseinfo *pi = &prselist[n];
  720.     long intadjust = 0;
  721.  
  722.     sl[0] = sl[1] = sl[2] = sl[3] = sl[4] = 0;
  723.     if (readopen() == 0) return 0;
  724.     for (long i = 0; i < 6; i++) {
  725.     switch (pi->rw[i]) {
  726.         case _none:
  727.         setdefaultproperties();
  728.         if (parseproperties() == 0) return 0;
  729.         s = addentry(idtable, name, pi->type);
  730.         p = addprim(pi->type, sl[0] ? sl[0]->p : 0,
  731.             sl[1] ? sl[1]->p : 0, sl[2] ? sl[2]->p : 0,
  732.             sl[3] ? sl[3]->p : 0, sl[4] ? sl[4]->p : 0,
  733.             intadjust ? constrainttype((long)(pi->ctype) + intadjust - 1) : pi->ctype, s);
  734.         if (p == 0) return 0;
  735.         if (f2 < 1.0e30) {
  736.             ((vertex *)p)->xw = f1;
  737.             ((vertex *)p)->yw = f2;
  738.             ((vertex *)p)->w = 1.0;
  739.         } else if (f1 < 1.0e30) {
  740.             // Warning:  this is used for angle and
  741.             // for length.  It counts on the 'value'
  742.             // field being in the same place in both
  743.             // structures.
  744.             ((length *)p)->value = f1;
  745.         }
  746.             return 1;
  747.         case _int2:
  748.         if (readinteger() == 0) return 0;
  749.         intadjust = longtoken;
  750.         if (intadjust != 1 && intadjust != 2) {
  751.             parseerror("Type must be 1 or 2");
  752.             return 0;
  753.         }
  754.         if ((i < 5) && pi->rw[i+1] != _none) {
  755.             if (readcomma() == 0) return 0;
  756.         }
  757.         break;
  758.         case _int4:
  759.         if (readinteger() == 0) return 0;
  760.         intadjust = longtoken;
  761.         if (intadjust != 1 && intadjust != 2 &&
  762.             intadjust != 3 && intadjust != 4) {
  763.             parseerror("Type must be 1, 2, 3, or 4");
  764.             return 0;
  765.         }
  766.         if ((i < 5) && pi->rw[i+1] != _none) {
  767.             if (readcomma() == 0) return 0;
  768.         }
  769.         break;
  770.         case _float:
  771.             if (readfloat() == 0) return 0;
  772.         if (f1 < 1.0e30) f2 = floattoken; else f1 = floattoken;
  773.         if ((i < 5) && pi->rw[i+1] != _none) {
  774.             if (readcomma() == 0) return 0;
  775.         }
  776.             break;
  777.         case _vertex:
  778.             sl[slistptr] = readvertex();
  779.         if (sl[slistptr++] == 0) return 0;
  780.         if ((i < 5) && pi->rw[i+1] != _none) {
  781.             if (readcomma() == 0) return 0;
  782.         }
  783.         break;
  784.         case _line:
  785.             sl[slistptr] = readline();
  786.         if (sl[slistptr++] == 0) return 0;
  787.         if ((i < 5) && pi->rw[i+1] != _none) {
  788.             if (readcomma() == 0) return 0;
  789.         }
  790.         break;
  791.         case _circle:
  792.             sl[slistptr] = readcircle();
  793.         if (sl[slistptr++] == 0) return 0;
  794.         if ((i < 5) && pi->rw[i+1] != _none) {
  795.             if (readcomma() == 0) return 0;
  796.         }
  797.         break;
  798.         case _conic:
  799.             sl[slistptr] = readconic();
  800.         if (sl[slistptr++] == 0) return 0;
  801.         if ((i < 5) && pi->rw[i+1] != _none) {
  802.             if (readcomma() == 0) return 0;
  803.         }
  804.         break;
  805.         case _length:
  806.             sl[slistptr] = readlength();
  807.         if (sl[slistptr++] == 0) return 0;
  808.         if ((i < 5) && pi->rw[i+1] != _none) {
  809.             if (readcomma() == 0) return 0;
  810.         }
  811.         break;
  812.     }
  813.     }
  814. }
  815.  
  816. long readmacrodef()
  817. {
  818.     tokentype t;
  819.     symtableentry *s;
  820.     char str[100];
  821.     
  822.     t = gettoken(globalfp);
  823.     if (t != Identifier) { parseerror("bad macro name"); return 0; }
  824.     s = lookup(idtable, texttoken);
  825.     if (s) { sprintf(str, "%s already defined", texttoken);
  826.          parseerror(str); return 0; }
  827.     addentry(idtable, texttoken, _macro);
  828.     if (readopen()==0) return 0;
  829.     /* XXX */
  830.     if (readclose()==0) return 0;
  831.     if (readopencurly()== 0) return 0;
  832.     if (readclosecurly() == 0) return 0;
  833. }
  834.  
  835. long parsereserved()
  836. {
  837.     char tmp[200];
  838.     text *t;
  839.     symtableentry *s;
  840.  
  841.     s = lookup(restable, texttoken);
  842.     if (s == 0) {
  843.     parseerror("bad initial token");
  844.     return 0;
  845.     }
  846.     switch(reswordtype(s->value)) {
  847.     case MAKETEXT:
  848.             if (readopen() == 0) return 0;
  849.         if (readstring() == 0) return 0;
  850.         strcpy(tmp, texttoken);
  851.         setdefaultproperties();
  852.         if (parseproperties() == 0) return 0;
  853.         s = addentry(idtable, "", _text);
  854.         t = (text *)addprim(_text, 0, 0, 0, 0, 0, NULLCONSTRAINT, s);
  855.         strcpy(t->str, tmp);
  856.         return 1;
  857.     case GEOMETRY:
  858.         if (0 == readstring()) return 0;
  859.         if (0 == readsemicolon()) return 0;
  860.         return 1;
  861.     case MACRO:
  862.         return readmacrodef();
  863.     default:
  864.         parseerror("missing identifier");
  865.         return 0;
  866.     }
  867. }
  868.  
  869. long parsemakevertex(char *vertname, long mtype)
  870. {
  871.     switch(mtype) {
  872.     case 1:        // free
  873.         return parsealine(0, vertname);
  874.     case 2:        // vonl
  875.         return parsealine(10, vertname);
  876.     case 3:        // vonc
  877.         return parsealine(11, vertname);
  878.     case 4:        // v_ll
  879.         return parsealine(2, vertname);
  880.     case 5:        // v_vvmid
  881.         return parsealine(1, vertname);
  882.     case 6:        // v_lc
  883.         return parsealine(4, vertname);
  884.     case 7:        // v_cc
  885.         return parsealine(5, vertname);
  886.     case 8:        // v_vvratio
  887.         return parsealine(7, vertname);
  888.     case 9:        // v_avv
  889.         return parsealine(8, vertname);
  890.     case 10:
  891.         return parsealine(9, vertname);
  892.     case 11:
  893.         return parsealine(6, vertname);
  894.     case 12:
  895.         return parsealine(12, vertname);
  896.     case 13:
  897.         return parsealine(3, vertname);
  898.     case 14:
  899.         return parsealine(40, vertname);
  900.     default:
  901.         return 0;
  902.     }
  903. }
  904.  
  905. long parsemakeline(char *linename, long mtype)
  906. {
  907.     switch(mtype) {
  908.     case 1:        // l_vv
  909.         return parsealine(13, linename);
  910.     case 2:        // l_vlperp
  911.         return parsealine(14, linename);
  912.     case 3:        // l_vlpar
  913.         return parsealine(15, linename);
  914.     case 4:        // l_vc
  915.         return parsealine(16, linename);
  916.     case 5:        // l_ccext
  917.         return parsealine(17, linename);
  918.     case 6:        // l_ccint
  919.         return parsealine(18, linename);
  920.     case 7:        // l_conicv
  921.         return parsealine(19, linename);
  922.     default:
  923.         return 0;
  924.     }
  925. }
  926.  
  927. long parsemakecircle(char *circname, long mtype)
  928. {
  929.     switch(mtype) {
  930.     case 1:        // c_vv
  931.         return parsealine(20, circname);
  932.     case 2:        // c_vvv
  933.         return parsealine(24, circname);
  934.     case 3:        // c_vlen
  935.         return parsealine(23, circname);
  936.     case 4:        // c_lll
  937.         return parsealine(25, circname);
  938.     case 5:
  939.         return parsealine(21, circname);
  940.     case 6:
  941.         return parsealine(22, circname);
  942.     default:
  943.         return 0;
  944.     }
  945. }
  946.  
  947. long parsemakebezier(char *bezname, long mtype)
  948. {
  949.     switch (mtype) {
  950.     case 1:
  951.         return parsealine(26, bezname);
  952.     default:
  953.         return 0;
  954.     }
  955. }
  956.  
  957. long parsemakelength(char *lenname, long mtype)
  958. {
  959.     switch (mtype) {
  960.     case 1:    // len_vv
  961.         return parsealine(29, lenname);
  962.     case 2:    // len_plus
  963.         return parsealine(31, lenname);
  964.     case 3:    // len_minus
  965.         return parsealine(32, lenname);
  966.     case 4:    // len_f
  967.         return parsealine(30, lenname);
  968.     case 5:    // len_times
  969.         return parsealine(33, lenname);
  970.     case 6:    // len_divide
  971.         return parsealine(34, lenname);
  972.     default:
  973.         return 0;
  974.     }
  975. }
  976.  
  977. long parsemakeangle(char *angname, long mtype)
  978. {
  979.     switch (mtype) {
  980.     case 1: // a_vvv
  981.         return parsealine(36, angname);
  982.     }
  983.     return 0;
  984. }
  985.  
  986. long parsemakeratio(char *ratname, long mtype)
  987. {
  988.     switch (mtype) {
  989.     case 1:
  990.         return parsealine(28, ratname);
  991.     default:
  992.         return 0;
  993.     }
  994. }
  995.  
  996. long parsemakeconic(char *conicname, long mtype)
  997. {
  998.     switch (mtype) {
  999.     case 1:
  1000.         return parsealine(27, conicname);
  1001.     case 2:
  1002.         return parsealine(39, conicname);
  1003.     default:
  1004.         return 0;
  1005.     }
  1006. }
  1007.  
  1008. long parseidentifier()
  1009. {
  1010.     symtableentry *s;
  1011.     char str[200];
  1012.     reservedword rw;
  1013.  
  1014.     // should be a new identifier
  1015.     if (s = lookup(idtable, texttoken)) {
  1016.     sprintf(str, "%s already declared", texttoken);
  1017.     parseerror(str);
  1018.     return 0;
  1019.     }
  1020.     strcpy(str, texttoken); // ugly!
  1021.     if (readequal() == 0) return 0;
  1022.     if (readreserved() == 0) return 0;
  1023.     s = lookup(restable, texttoken);
  1024.     rw = s->value;
  1025.     switch (reswordtype(rw)) {
  1026.     case MAKEVERTEX:
  1027.         return parsemakevertex(str, minortype);
  1028.     case MAKELINE:
  1029.         return parsemakeline(str, minortype);
  1030.     case MAKECIRCLE:
  1031.         return parsemakecircle(str, minortype);
  1032.     case MAKEBEZIER:
  1033.         return parsemakebezier(str, minortype);
  1034.     case MAKELENGTH:
  1035.         return parsemakelength(str, minortype);
  1036.     case MAKERATIO:
  1037.         return parsemakeratio(str, minortype);
  1038.     case MAKEANGLE:
  1039.         return parsemakeangle(str, minortype);
  1040.     case MAKEVPATH:
  1041.         break;
  1042.     case MAKEANIMATE:
  1043.         break;
  1044.     case MAKECONIC:
  1045.         return parsemakeconic(str, minortype);
  1046.     default:
  1047.         sprintf(str, "wacko constructor: %s", texttoken);
  1048.         return 0;
  1049.     }
  1050.     return 1;
  1051. }
  1052.  
  1053. long parsecomment()
  1054. {
  1055.     comment *t;
  1056.     symtableentry *s;
  1057.  
  1058.     s = addentry(idtable, "", _comment);
  1059.     t = (comment *)addprim(_comment, 0, 0, 0, 0, 0, NULLCONSTRAINT, s);
  1060.     if (t == 0) return 0;
  1061.     strncpy(t->str, texttoken, 149);
  1062.     return 1;
  1063. }
  1064.  
  1065. long parseline()
  1066. {
  1067.     switch (gettoken(globalfp)) {
  1068.     case Comment:
  1069.         if (parsecomment()) return 1;
  1070.         return 0;
  1071.     case Reserved:
  1072.         if (parsereserved()) return 1;
  1073.         return 0;
  1074.     case Identifier:
  1075.         if (parseidentifier()) return 1;
  1076.         return 0;
  1077.     case Eof:
  1078.         return -1;
  1079.     case Error:
  1080.         return 0;
  1081.     case Open:
  1082.     case Close:
  1083.     case Semicolon:
  1084.     case Comma:
  1085.     case Equal:
  1086.     case Integer:
  1087.     case Float:
  1088.     case Str:
  1089.     case OpenCurly:
  1090.     case CloseCurly:
  1091.         parseerror("Unexpected token");
  1092.         return 0;
  1093.     }
  1094. }
  1095.  
  1096. long parsefile(FILE *fp)
  1097. {
  1098.     globalfp = fp;
  1099.     long k;
  1100.  
  1101.     while (1) {
  1102.         if ((k = parseline()) == 0) return 0;
  1103.     if (k == -1) return 1;
  1104.     }
  1105. }
  1106.